package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.Operation;
import com.example.demo.entity.UOperation;
import com.example.demo.entity.User;
import com.example.demo.entity.vo.OperationVo;
import com.example.demo.exception.bizException.BizException;
import com.example.demo.mapper.UOperationMapper;
import com.example.demo.service.UOperationService;
import com.example.demo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
* <p>
*  服务实现类
* </p>
*
* @author cy
* @since 2020-10-10
*/
@Slf4j
@Service
public class UOperationServiceImpl extends ServiceImpl<UOperationMapper, UOperation> implements UOperationService {

    @Autowired
    private UserService userService;

    @Override
    public Page<UOperation> listUOperationsByPage(int page, int pageSize, String factor) {
        log.info("正在执行分页查询uOperation: page = {} pageSize = {} factor = {}",page,pageSize,factor);
        QueryWrapper<UOperation> queryWrapper =  new QueryWrapper<UOperation>().like("", factor);
        //TODO 这里需要自定义用于匹配的字段,并把wrapper传入下面的page方法
        Page<UOperation> result = super.page(new Page<>(page, pageSize));
        log.info("分页查询uOperation完毕: 结果数 = {} ",result.getRecords().size());
        return result;
    }

    @Override
    public UOperation getUOperationById(int id) {
        log.info("正在查询uOperation中id为{}的数据",id);
        UOperation uOperation = super.getById(id);
        log.info("查询id为{}的uOperation{}",id,(null == uOperation?"无结果":"成功"));
        return uOperation;
    }

    @Override
    public List<Integer> getUOperationByUId(int uId) {
        log.info("正在查询uOperation中uId为{}的数据",uId);
        List<UOperation> uOperations = super.list(new QueryWrapper<UOperation>().eq("u_id",uId));
        log.info("查询uId为{}的uOperation{}",uId,(null == uOperations?"无结果":"成功"));
        return uOperations == null?new ArrayList<>():this.operationIdsUtil(uOperations);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertUOperation(OperationVo operationVo) {
        log.info("正在插入uOperation");
        if (!operationVo.getOperations().isEmpty()){
            log.info("如果权限列表不是空，将该用户设为管理员");
            User user = new User();
            user.setUserId(operationVo.getUId());
            user.setState(User.ADMIN);
            userService.updateUser(user);
        }
        log.info("先删除该用户原来的权限");
        super.remove(new QueryWrapper<UOperation>().eq("u_id",operationVo.getUId()));
        List<UOperation> uOperations = this.operationUtil(operationVo);
        for (UOperation uOperation:uOperations) {
            if (super.save(uOperation)) {
                log.info("插入uOperation成功,用户id为{}，权限id为{}",uOperation.getUId(),uOperation.getOId());
            } else {
                log.error("插入uOperation失败");
                throw new BizException("添加失败");
            }
        }
        return operationVo.getUId();
    }

    @Override
    public int deleteUOperationById(int id) {
        log.info("正在删除id为{}的uOperation",id);
        if (super.removeById(id)) {
            log.info("删除id为{}的uOperation成功",id);
            return id;
        } else {
            log.error("删除id为{}的uOperation失败",id);
            throw new BizException("删除失败[id=" + id + "]");
        }
    }

    @Override
    public int updateUOperation(UOperation uOperation) {
        log.info("正在更新id为{}的uOperation",uOperation.getUId());
        if (super.updateById(uOperation)) {
            log.info("更新d为{}的uOperation成功",uOperation.getUId());
            return uOperation.getUId();
        } else {
            log.error("更新id为{}的uOperation失败",uOperation.getUId());
            throw new BizException("更新失败[id=" + uOperation.getUId() + "]");
        }
    }

    private List<UOperation> operationUtil(OperationVo operationVo){
        List<UOperation> uOperations = new ArrayList<>();
        for (Operation operation:operationVo.getOperations()) {
            uOperations.add(new UOperation(operationVo.getUId(),operation.getOperationId()));
        }
        return uOperations;
    }

    private List<Integer> operationIdsUtil(List<UOperation> uOperations){
        List<Integer> list = new ArrayList<>();
        for (UOperation uOperation:uOperations) {
            list.add(uOperation.getOId());
        }
        return list;
    }

}
